import {warningMessage} from "@/utils/message";
import {MyMapOpt} from "@/class/map/myMapOpt";
import {PolygonData} from "@/class/map/Polygon";
import {PolylineData} from "@/class/map/Polyline";
import {MarkerData} from "@/class/map/Maker";
import {TrackData} from "@/class/map/Track";

const getBounds=function (){
    const result1 ={
        northEast:[180,90],
        southWest:[-180,-90]
    }
    /**
     * 通过闭包的方式返回
     * @param path 路径数组
     * @returns {{southWest: number[], northEast: number[]}}
     */
    const getBound=function(path){
        path.map(tPath=>{
            if(!isPosition(tPath)){
                getBound(tPath)
            }else{
                if(result1.northEast[0]>tPath[0])
                    result1.northEast[0]=tPath[0]
                if(result1.northEast[1]>tPath[1])
                    result1.northEast[1]=tPath[1]
                if(result1.southWest[0]<tPath[0])
                    result1.southWest[0]=tPath[0]
                if(result1.southWest[1]<tPath[1])
                    result1.southWest[1]=tPath[1]
            }
        })
        return result1;
    }
    return getBound;
}
const isPosition=function(array){
    if(Array.isArray(array)
        &&(!Array.isArray(array[0]))
        &&(!Array.isArray(array[1])))
        return true;
    else
        return false;
}

const isObjectChanged=function (source, comparison) {
    let isChanged = false
    for (let key in source) {
        // 由于Object和Array都属于我们要特殊判断的数据类型，所以要提前做一下判断
        if (typeof(source[key]) === 'object' || typeof(source[key]) === 'array') {
            // 由于isChanged默认值就是false,所以我们只在isObjectChanged返回true的时候改变状态
            if (isObjectChanged(source[key], comparison[key])) {
                isChanged = true
            }
        } else if (source[key] !== comparison[key]) {
            isChanged = true
        }
    }
    return isChanged
}


const sleep = function (time) {
    var timeStamp = new Date().getTime();
    var endTime = timeStamp + time;
    while (true) {
        if (new Date().getTime() > endTime) {
            return;
        }
    }
}
// 定义速度区间和对应的十六进制颜色代码映射表
const speedColorMap = [
    { minSpeed: 0, maxSpeed: 10, color: "#00008B" }, // 深蓝色，极慢
    { minSpeed: 10, maxSpeed: 20, color: "#006400" }, // 深绿色，很慢
    { minSpeed: 20, maxSpeed: 30, color: "#008080" }, // 深青色，慢
    { minSpeed: 30, maxSpeed: 40, color: "#00BFFF" }, // 深天蓝，稍慢
    { minSpeed: 40, maxSpeed: 50, color: "#FFFF00" }, // 黄色，中等
    { minSpeed: 50, maxSpeed: 60, color: "#FFD700" }, // 金色，稍快
    { minSpeed: 60, maxSpeed: 70, color: "#FFA500" }, // 橙色，快
    { minSpeed: 70, maxSpeed: 80, color: "#FF6347" }, // 番茄红，较快
    { minSpeed: 80, maxSpeed: 90, color: "#FF4500" }, // 橙红色，很快
    { minSpeed: 90, maxSpeed: 100, color: "#FF1493" }, // 深粉红，非常快
    { minSpeed: 100, maxSpeed: 110, color: "#FF0000" }, // 红色，极快
    { minSpeed: 110, maxSpeed: 120, color: "#8B0000" }, // 暗红色，超极快
    { minSpeed: 120, maxSpeed: Infinity, color: "#FF00FF" } // 品红色，爆表速度
];
// 根据速度值获取对应的颜色
function getColorBySpeed(speed) {
    for (let i = 0; i < speedColorMap.length; i++) {
        const { minSpeed, maxSpeed, color } = speedColorMap[i];
        if (speed >= minSpeed && speed < maxSpeed) {
            return color;
        }
    }
    // 如果没有匹配到任何区间，返回默认颜色（这里返回灰色）
    return "#808080";
}
const shapefile = require('shapefile');
const chardet = require('chardet');
const iconv = require('iconv-lite');

// 读取文件为 ArrayBuffer
const readFileAsArrayBuffer = (file) => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = () => reject(reader.error);
        reader.readAsArrayBuffer(file);
    });
};

// 处理 .dbf 文件编码转换
const processDbfFile = async (dbfFile) => {
    try {
        const dbfArrayBuffer = await readFileAsArrayBuffer(dbfFile);
        const dbfUint8Array = new Uint8Array(dbfArrayBuffer);
        const detectedEncoding = chardet.detect(dbfUint8Array);
        console.log('检测到的 .dbf 文件编码格式:', detectedEncoding);

        let dbfUtf8ArrayBuffer;
        if (detectedEncoding && detectedEncoding !== 'UTF-8') {
            const dbfUtf8String = iconv.decode(dbfUint8Array, detectedEncoding);
            dbfUtf8ArrayBuffer = new TextEncoder().encode(dbfUtf8String).buffer;
        } else {
            dbfUtf8ArrayBuffer = dbfArrayBuffer;
        }

        if (!dbfUtf8ArrayBuffer) {
            throw new Error('无法确定 .dbf 文件的编码');
        }

        return dbfUtf8ArrayBuffer;
    } catch (error) {
        console.error('处理 .dbf 文件时出错:', error);
        throw error;
    }
};

// 检查文件名是否匹配
const areFilesMatched = (shpFile, dbfFile) => {
    const shpBaseName = shpFile.name.replace(/\.shp$/i, '');
    const dbfBaseName = dbfFile.name.replace(/\.dbf$/i, '');
    return shpBaseName === dbfBaseName;
};

// 解析 Shapefile
const getShapeFile = async (event) => {
    const files = event.target.files;
    if (files.length === 0) {
        alert('请选择文件。');
        return;
    }

    let shpFile, dbfFile;
    for (let i = 0; i < files.length; i++) {
        const file = files[i];
        if (file.name.endsWith('.shp')) {
            shpFile = file;
        } else if (file.name.endsWith('.dbf')) {
            dbfFile = file;
        }
    }

    if (!shpFile || !dbfFile) {
        alert('请同时选择 .shp 和 .dbf 文件。');
        return;
    }

    if (!areFilesMatched(shpFile, dbfFile)) {
        alert('.shp 和 .dbf 文件名不匹配。');
        return;
    }

    try {
        const dbArrayBuffer = await readFileAsArrayBuffer(dbfFile);
        const shpArrayBuffer = await readFileAsArrayBuffer(shpFile);
        const geojson = await shapefile.read(shpArrayBuffer, dbArrayBuffer);
        const {features,bbox} = geojson;
        return features;
    } catch (error) {
        alert(`解析 Shapefile 文件时出错: ${error.message}`);
        console.error('解析 Shapefile 文件时出错:', error);
        return null;
    }
};
/**
 * 更加item返回对应的数据类型
 * @param item
 */
export function getMapDateByType(item) {
    let data;
    switch (item.mapData.type) {
        case MyMapOpt.MapType.Polygon:
            data = new PolygonData(item);
            break;
        case MyMapOpt.MapType.Polyline:
            data = new PolylineData(item);
            break;
        case MyMapOpt.MapType.Marker:
            data = new MarkerData(item);
            break;
        case MyMapOpt.MapType.Track:
            data = new TrackData(item)
            break;
    }
    return data;
}
export {getBounds,isObjectChanged,sleep,getColorBySpeed,getShapeFile}